package consulTest.common;

import cn.hutool.core.util.ObjectUtil;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import java.util.Optional;

@Getter
@Setter
@ToString
@NoArgsConstructor
public class Response<T> implements Serializable {
    /**
     * 默认成功消息
     */
    static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";
    /**
     * 默认失败消息
     */
    static final String DEFAULT_FAILURE_MESSAGE = "操作失败";
    /**
     * 默认为空消息
     */
    static final String DEFAULT_NULL_MESSAGE = "暂无承载数据";

    /**
     * 操作成功返回0
     */
    public static final int CODE = ResultCode.SUCCESS.getCode();

    public static final String MESSAGE = ResultCode.SUCCESS.getMessage();

    private Response(IResultCode resultCode) {
        this(resultCode, null, resultCode.getMessage());
    }

    private Response(IResultCode resultCode, String msg) {
        this(resultCode, null, msg);
    }

    private Response(IResultCode resultCode, T data) {
        this(resultCode, data, resultCode.getMessage());
    }

    private Response(IResultCode resultCode, T data, String msg) {
        this(resultCode.getCode(), data, msg);
    }

    private Response(int errorCode, T data, String message) {
        this.errorCode = errorCode;
        this.data = data;
        this.message = message;
        this.reqId = getReqId();
    }


    /**
     * 操作码(取值来自自定义异常的getCode())
     */
    private int errorCode = CODE;

    /**
     * 错误信息(内容来自自定义异常的getMessage())
     */
    private String message = MESSAGE;

    private String reqId = null;

    /**
     * 返回的数据
     */
    private T data;

    /**
     * 判断返回是否为成功
     *
     * @param result Result
     * @return 是否成功
     */
    public static boolean isSuccess(@Nullable Response<?> result) {
        return Optional.ofNullable(result).map(x -> ObjectUtil.equal(ResultCode.SUCCESS.code, x.errorCode)).orElse(Boolean.FALSE);
    }

    /**
     * 返回R
     *
     * @param data 数据
     * @param <T>  T 泛型标记
     * @return R
     */
    public static <T> Response<T> data(T data) {
        return data(data, MESSAGE);
    }

    /**
     * 返回R
     *
     * @param data    数据
     * @param message 消息
     * @param <T>     T 泛型标记
     * @return R
     */
    public static <T> Response<T> data(T data, String message) {
        return data(ResultCode.SUCCESS.code, data, message);
    }

    /**
     * 返回R
     *
     * @param code    状态码
     * @param data    数据
     * @param message 消息
     * @param <T>     T 泛型标记
     * @return R
     */
    public static <T> Response<T> data(int code, T data, String message) {
        return new Response<>(code, data, data == null ? DEFAULT_NULL_MESSAGE : message);
    }

    public static <T> Response<T> success() {
        return new Response<>(ResultCode.SUCCESS, ResultCode.SUCCESS.getMessage());
    }

    /**
     * 返回R
     *
     * @param message 消息
     * @param <T>     T 泛型标记
     * @return R
     */
    public static <T> Response<T> success(String message) {
        return new Response<>(ResultCode.SUCCESS, message);
    }

    /**
     * 返回R
     *
     * @param resultCode 业务代码
     * @param <T>        T 泛型标记
     * @return R
     */
    public static <T> Response<T> success(IResultCode resultCode) {
        return new Response<>(resultCode);
    }

    /**
     * 返回R
     *
     * @param resultCode 业务代码
     * @param message    消息
     * @param <T>        T 泛型标记
     * @return R
     */
    public static <T> Response<T> success(IResultCode resultCode, String message) {
        return new Response<>(resultCode, message);
    }

    public static <T> Response<T> fail() {
        return new Response<>(ResultCode.FAILURE, ResultCode.FAILURE.getMessage());
    }

    /**
     * 返回R
     *
     * @param msg 消息
     * @param <T> T 泛型标记
     * @return R
     */
    public static <T> Response<T> fail(String msg) {
        return new Response<>(ResultCode.FAILURE, msg);
    }

    /**
     * 返回R
     *
     * @param code    状态码
     * @param message 消息
     * @param <T>     T 泛型标记
     * @return R
     */
    public static <T> Response<T> fail(int code, String message) {
        return new Response<>(code, null, message);
    }

    /**
     * 返回R
     *
     * @param resultCode 业务代码
     * @param <T>        T 泛型标记
     * @return R
     */
    public static <T> Response<T> fail(IResultCode resultCode) {
        return new Response<>(resultCode);
    }

    /**
     * 返回R
     *
     * @param resultCode 业务代码
     * @param msg        消息
     * @param <T>        T 泛型标记
     * @return R
     */
    public static <T> Response<T> fail(IResultCode resultCode, String msg) {
        return new Response<>(resultCode, msg);
    }

}
